home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / asmlib30.zip / FLOAT.DOC < prev    next >
Text File  |  1993-04-08  |  21KB  |  777 lines

  1.  
  2. ***********************  FLOATING-POINT DATA  *******************************
  3.  
  4. ASMLIB floating-point data subroutines (c) copyright 1991 Douglas Herr
  5. all rights reserved
  6.  
  7. ASMLIB recognizes two floating point formats: IEEE-standard single-
  8. precision, and IEEE-standard double-precision.  Single-precision
  9. floating point numbers are 4 bytes long, and are referred to as float4
  10. or simply f4, while double-precision floating point numbers are 8 bytes
  11. long, which I describe as float8 or f8.
  12.  
  13.  
  14.  
  15. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  16.  
  17. ADDF4:     add two float4 values
  18. Source:    addf4.asm
  19.  
  20. 80x87 not required
  21.  
  22. Call with: DS:[SI] pointing to value0, ES:[DI] pointing to value1
  23.            both values must be float4 values in IEEE format
  24. Returns:   if CF = 0, value0 is replaced by the sum
  25.            if CF = 1, the sum would result in an overflow; neither
  26.            value is changed
  27. Uses:      CF
  28.  
  29. Example:
  30.  
  31. include asm.inc
  32.  
  33. extrn addf4:proc
  34.  
  35. .data
  36. value0  dd 123.456
  37. value1  dd -67.4
  38.  
  39. .code
  40. ; program fragment assumes DS:@data
  41.          .
  42.          .
  43.          .
  44.         push    ds
  45.         pop     es           ; ES = DS
  46.         assume  es:@data
  47.         lea     si,value0
  48.         lea     di,value1
  49.         call    addf4
  50.  
  51. ; note that this can be used for subtraction by changing the sign
  52. ; of one of the values
  53. ;
  54. ; changing the sign is trivial: if DS:[SI] points to a float4 value,
  55. ; the sign is changed with
  56. ;
  57. ;      xor    byte ptr 3[si],10000000b
  58.  
  59.  
  60. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  61.  
  62. ADDF8:     add two float8 values
  63. Source:    addf8.asm
  64.  
  65. 80x87 not required
  66.  
  67. Call with: DS:[SI] pointing to value0, ES:[DI] pointing to value1
  68.            both values must be float8 values in IEEE format
  69. Returns:   if CF = 0, value0 is replaced by the sum
  70.            if CF = 1, the sum would result in an overflow; neither
  71.            value is changed
  72. Uses:      CF
  73.  
  74. Example:
  75.  
  76. include asm.inc
  77.  
  78. extrn addf8:proc
  79.  
  80. .data
  81.  
  82. value0  dq 123.456
  83. value1  dq -67.4
  84.  
  85. .code
  86. ; program fragment assumes DS:@data
  87.          .
  88.          .
  89.          .
  90.         push    ds
  91.         pop     es           ; ES = DS
  92.         assume  es:@data
  93.         lea     si,value0
  94.         lea     di,value1
  95.         call    addf8
  96.  
  97. ; note that this can be used for subtraction by changing the sign
  98. ; of one of the values
  99. ;
  100. ; changing the sign is trivial: if DS:[SI] points to a float8 value,
  101. ; the sign is changed with
  102. ;
  103. ;      xor    byte ptr 7[si],10000000b
  104.  
  105.  
  106.  
  107. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  108.  
  109. CMPF4:      compare two float4 values
  110. Source:     cmpf4.asm
  111.  
  112. CMPF8:      compare two float8 values
  113. Source:     cmpf8.asm
  114.  
  115. 80x87 NOT required
  116.  
  117. Call with:  DS:[SI] pointing to value 0
  118.             ES:[DI] pointing to value 1
  119. Returns:    if ZF = 1, values are equal
  120.             if SF = 1, value 1 is larger
  121. Uses:       zero flag (ZF), sign flag (SF)
  122. Example:
  123.  
  124. include  asm.inc
  125.  
  126. extrn    cmpf4:proc
  127.  
  128. .data
  129. v0       dd 12.345
  130. v1       dd 17.04
  131.  
  132. .code
  133. ; program fragment assumes DS:@data
  134.          .
  135.          .
  136.          .
  137.          push   ds
  138.          pop    es               ; in this example, both values are in DGROUP
  139.          assume es:@data
  140.          lea    si,v0            ; point DS:[SI] to value 0
  141.          lea    di,v1            ; point ES:[DI] to value 1
  142.          call   cmpf4            ; compare
  143.          js     value1           ; value 1 is larger if SF = 1
  144.          je     equal            ; both float4 values are identical if ZF = 1
  145.                                  ; otherwise value 0 is larger
  146.  
  147.  
  148. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  149.  
  150. DIVI2:      divides integer in AX by integer in DX, returning float4 quotient
  151. Source:     divi2.asm (i2tof4.asm, invf4.asm, mulf4.asm)
  152.  
  153. 80x87 not required
  154.  
  155. Call with:  AX, DX = I2 values; DX <> 0
  156.             DS:[BX] pointing to 4-byte buffer for quotient
  157.             DivI2 does not check for divide-by-zero errors
  158.             make sure DX <> 0 and you'll be OK
  159. Returns:    quotient at DS:[BX], f4 format
  160. Uses:       nothing; all flags and registers are saved
  161. Example:
  162.  
  163. include asm.inc
  164.  
  165. extrn   divi2:proc
  166.  
  167. .data
  168. f4data  dd ?                     ; 4 bytes for resulting quotient
  169.  
  170. .code
  171. ; program fragment assumes DS:@data
  172.         .
  173.         .
  174.         .
  175.         mov    ax,17             ; I want to calculate 17/47
  176.         mov    dx,47             ; don't ask me why
  177.         lea    bx,f4data         ; point to 4-byte data area
  178.         call   divi2
  179.  
  180.  
  181. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  182.  
  183. F4TOF8:     converts a float4 value to float8 format
  184. Source:     f4tof8.asm
  185.  
  186. 80x87 not required
  187.  
  188. Call with:  DS:[SI] pointing to float4 value
  189.             ES:[DI] pointing to 8-byte buffer for float8 value
  190. Returns:    CF = 0 if successful
  191.             CF = 1 if the float4 value is invalid
  192. Uses:       CF; all other flags and registers are saved
  193. Example:
  194.  
  195. include asm.inc
  196.  
  197. extrn  f4tof8:proc
  198.  
  199. .data
  200. float4      dd 123.456
  201. float8      dq ?
  202.  
  203. .code
  204. ; program fragment assumes DS:@data
  205.              .
  206.              .
  207.              .
  208.             push    ds
  209.             pop     es           ; ES = DS
  210.             assume  es:@data
  211.             lea     si,float4           ; DS:[SI] points to float4 value
  212.             lea     di,float8           ; ES:[DI] points to float8 buffer
  213.             call    f4tof8
  214.             jc      oops                ; go to error handler if problem
  215.  
  216.  
  217.  
  218.  
  219. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  220.  
  221. F4TOI2:     copies the integer portion of a float4 value to AX
  222. Source:     f4toi2.asm
  223.  
  224. 80x87 not required
  225.  
  226. Note:       only the integer portion of the value is converted; decimals
  227.             are truncated
  228. Call with:  DS:[SI] pointing to a float4 value
  229. Returns:    if CF = 0, AX = integer value
  230.             if CF = 1, float4 value is too large (if positive)
  231.                        or is too small (if negtive)
  232. Uses:       AX, CF; all other flags and registers are saved
  233. Example:
  234.  
  235. include asm.inc
  236.  
  237. extrn   f4toi2:proc
  238.  
  239. .data
  240. float4  dd  1234.567
  241.  
  242. .code
  243. ; program fragment assumes DS:@data
  244.         .
  245.         .
  246.         .
  247.         lea  si,float4
  248.         call f4toi2
  249.         jc   oops                     ; gotta fix something if error
  250.  
  251.  
  252.  
  253. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  254.  
  255. F4TOI4:     copies the long integer portion of a float4 value to DX:AX
  256. Source:     f4toi4.asm
  257.  
  258. 80x87 not required
  259.  
  260. Note:       only the integer portion of the value is converted; decimals
  261.             are truncated
  262. Call with:  DS:[SI] pointing to a float4 value
  263. Returns:    if CF = 0, DX:AX = long integer value
  264.             if CF = 1, float4 value is too large (if positive)
  265.                        or is too small (if negtive)
  266. Uses:       AX, DX, CF; all other flags and registers are saved
  267. Example:
  268.  
  269. include asm.inc
  270.  
  271. extrn   f4toi4:proc
  272.  
  273. .data
  274. float4  dd  1234.567
  275.  
  276. .code
  277. ; program fragment assumes DS:@data
  278.         .
  279.         .
  280.         .
  281.         lea    si,float4
  282.         call   f4toi4
  283.         jc     oops                   ; gotta fix something if error
  284.  
  285.  
  286.  
  287.  
  288. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  289.  
  290. F8TOF4:     converts a float8 value to float4 format
  291. Source:     f8tof4.asm
  292.  
  293. 80x87 not required
  294.  
  295. Call with:  DS:[SI] pointing to float8 value
  296.             ES:[DI] pointing to 4-byte buffer for float4 value
  297. Returns:    CF = 0 if no error
  298.             CF = 1 float8 number overflowed to infinity
  299.                    or underflowed to zero
  300. Uses:       CF; all other flags and registers are saved
  301. Example:
  302.  
  303. include asm.inc
  304.  
  305. extrn  f8tof4:proc
  306.  
  307. .data
  308. float8      dq 123.456
  309. float4      dd ?
  310.  
  311. .code
  312. ; program fragment assumes DS:@data
  313.              .
  314.              .
  315.              .
  316.             push    ds
  317.             pop     es           ; ES = DS
  318.             assume  es:@data
  319.             lea     si,float8           ; DS:[SI] points to float8 value
  320.             lea     di,float4           ; ES:[DI] points to float4 buffer
  321.             call    f8tof4
  322.             jc      oops                ; go to error handler if problem
  323.  
  324.  
  325.  
  326.  
  327. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  328.  
  329. I2TOF4:     convert integer value to float4 IEEE format
  330. Source:     i2tof4.asm
  331.  
  332. 80x87 not required
  333.  
  334. Call with:  DS:[BX] pointing to 4-byte buffer for float4 value
  335.             AX = signed integer value to convert
  336. Returns:    converted value in float4 IEEE format at DS:[BX]
  337. Uses:       nothing; all registers and flags are saved
  338. Example:
  339.  
  340. include asm.inc
  341.  
  342. extrn   i2tof4:proc
  343.  
  344. .data
  345. float4  dd ?                   ; initial value undefined
  346.  
  347. .code
  348. ; program fragment assumes DS:@data
  349.         .
  350.         .
  351.         .
  352.         mov    ax,12345        ; signed integer value in AX
  353.         lea    bx,float4       ; this is where I want the resulting value
  354.         call   i2tof4
  355.  
  356.  
  357.  
  358. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  359.  
  360. I4TOF4:     convert long integer value to float4 IEEE format
  361. Source:     i4tof4.asm
  362.  
  363. 80x87 not required
  364.  
  365. Call with:  DS:[BX] pointing to 4-byte buffer for float4 value
  366.             DX:AX = signed long integer value to convert
  367.                     (high word in DX)
  368. Returns:    converted value in float4 IEEE format at DS:[BX]
  369. Uses:       nothing; all registers and flags are saved
  370. Example:
  371.  
  372. include asm.inc
  373.  
  374. extrn   i4tof4:proc
  375.  
  376. .data
  377. float4  dd ?                          ; initial value undefined
  378. longint dd -123456789
  379.  
  380. .code
  381. ; program fragment assumes DS:@data
  382.         .
  383.         .
  384.         .
  385.         mov    ax,word ptr longint    ; low word of signed long integer
  386.         mov    dx,word ptr longint+2  ; high word of signed long integer
  387.         lea    bx,float4              ; point to buffer for converted value
  388.         call   i4tof4
  389.  
  390.  
  391.  
  392. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  393.  
  394. INVF4:      calculate the inverse of a float4 value
  395. Source:     invf4.asm
  396.  
  397. 80x87 not required
  398.  
  399. Call with:  DS:[SI] = address of float4 value
  400. Returns:    DS:[SI] = address of 1/value
  401.             previous value is overwritten
  402. Uses:       nothing
  403. Example:
  404.  
  405. include asm.inc
  406.  
  407. extrn   invf4:proc
  408.  
  409. .code
  410. ; program fragment assumes DS:@data
  411.         .
  412.         .
  413.         .
  414.         lea   si,float4          ; point to float4 value
  415.         call  invf4              ; original value replaced with inverse
  416.  
  417.  
  418.  
  419. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  420.  
  421. MAXF4, MAXF4b: find maximum value in single-precision real-number array
  422. Source:        small & medium models: maxf4.asm
  423.                huge model: maxf4.asm (lowDS2hi.asm)
  424.  
  425. MINF4, MINF4b: find minimum value in single-precision real-number array
  426. Source:        small & medium models: minf4.asm
  427.                huge model: minf4.asm (lowDS2hi.asm)
  428.  
  429. 80x87 not required
  430.  
  431. Call with:  ES:[DI] pointing to array element at start of search
  432.             CX = number of array elements to search
  433.             For maxf4b or minf4b, call with BX = byte increment between
  434.             array elements.  Maxf4 and minf4 assume byte increment = 4.
  435. Returns:    AX = array element number with maximum or minimum value
  436.             note that the offset of that value is DI + (AX shl 2).
  437.             With maxf4b and minf4b, the offset of the value is
  438.             DI + (AX * BX).
  439.             AX = -1 if maxf4 was called with CX = 0
  440. Uses:       AX
  441. Example:
  442.  
  443. include asm.inc
  444.  
  445. extrn  maxf4:proc
  446.  
  447. .data
  448. floatdata   dd 1500 dup(0)
  449.  
  450. .code
  451. ; program fragment assumes DS:@data
  452. ; program provides values for the array
  453.        .
  454.        .
  455.        .
  456.        push   ds
  457.        pop    es
  458.        assume es:@data
  459.        lea    di,floatdata      ; ES:[DI] points to the data array
  460.        mov    cx,1500           ; search entire array
  461.        call   maxf4             ; returns with AX = array element
  462.  
  463.  
  464.  
  465. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  466.  
  467. MAXF8, MAXF8b: find maximum value in double-precision real-number array
  468. Source:        maxf8.asm
  469.  
  470. MINF8, MINF8b: find minimum value in double-precision real-number array
  471. Source:        minf8.asm
  472.  
  473. 80x87 not required
  474.  
  475. Call with:  ES:[DI] pointing to array element at start of search
  476.             CX = number of array elements to search
  477.             For maxf8b or minf8b, call with BX = byte increment between
  478.             array elements.  Maxf8 and minf8 assume byte increment = 8.
  479. Returns:    AX = array element number with maximum or minimum value
  480.             note that the offset of that value is DI + (AX shl 3)
  481.             With maxf8b and minf8b, the offset of the value is
  482.             DI + (AX * BX).
  483.             AX = -1 if maxf8 was called with CX = 0
  484. Uses:       AX
  485. Example:
  486.  
  487. include asm.inc
  488.  
  489. extrn  maxf8:proc
  490.  
  491. .data
  492. floatdata   dq 1500 dup(0)
  493.  
  494. .code
  495. ; program fragment assumes DS:@data
  496. ; program provides values for the array
  497.        .
  498.        .
  499.        .
  500.        push   ds
  501.        pop    es
  502.        assume es:@data
  503.        lea    di,floatdata      ; ES:[DI] points to the data array
  504.        mov    cx,1500           ; search entire array
  505.        call   maxf8             ; returns with AX = array element
  506.        mov    cl,3
  507.        shl    ax,cl
  508.        add    di,ax             ; ES:[DI] points to maximum value
  509.  
  510.  
  511.  
  512. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  513.  
  514. MULF4:      multiplies two float4 values
  515. Source:     mulf4.asm
  516.  
  517. 80x87 not required
  518.  
  519. Call with:  DS:[SI] pointing to value0, ES:[DI] pointing to value1
  520. Returns:    if CF = 0, no error; product replaces value0 at DS:[SI]
  521.             if CF = 1, the product is either zero or infinity (value0 is lost)
  522. Uses:       CF; all other flags and registers are saved
  523. Example:
  524.  
  525. include asm.inc
  526.  
  527. extrn  mulf4:proc
  528.  
  529. .data
  530. value0   dd 1.234
  531. value1   dd 0.5
  532.  
  533. .code
  534. ; program fragment assumes DS:@data
  535.          .
  536.          .
  537.          .
  538.          push   ds
  539.          pop    es
  540.          assume es:@data
  541.          lea    si,value0
  542.          lea    di,value1
  543.          call   mulf4
  544.  
  545.  
  546. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  547.  
  548. MULF4TEN:   multiply a float4 value by 10
  549. Source:     mulf4ten.asm (mulf4.asm)
  550.  
  551. 80x87 not required
  552.  
  553. Call with:  DS:[SI] pointing to float4 value
  554.             MulF4Ten is front-end code for MulF4, which saves ES and DI,
  555.             points ES:[DI] to f4 data equalling 10.0, calls MulF4, then
  556.             restores ES and DI.
  557. Returns:    if CF = 0, float4 value at DS:[SI] multiplied by 10.0
  558.             if CF = 1, the product is either 0 or infinity
  559. Uses:       CF; all other flags and registers are saved
  560. Example:
  561.  
  562. include asm.inc
  563.  
  564. extrn  mulf4ten:proc
  565.  
  566. .data
  567. value0   dd 1.234
  568.  
  569. .code
  570. ; program fragment assumes DS:@data
  571.          .
  572.          .
  573.          .
  574.          lea    si,value0
  575.          call   mulf4ten
  576.  
  577.  
  578. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  579.  
  580. MULF8:      multiplies two float8 values
  581. Source:     mulf8.asm (mpmul.asm)
  582.  
  583. 80x87 not required
  584.  
  585. Call with:  DS:[SI] pointing to value0, ES:[DI] pointing to value1
  586. Returns:    if CF = 0, no error; product replaces value0 at DS:[SI]
  587.             if CF = 1, the product is either zero or infinity (value0 is lost)
  588. Uses:       CF; all other flags and registers are saved
  589. Example:
  590.  
  591. include asm.inc
  592.  
  593. extrn  mulf8:proc
  594.  
  595. .data
  596. value0   dq 1.2347349
  597. value1   dq 0.5
  598.  
  599. .code
  600. ; program fragment assumes DS:@data
  601.          .
  602.          .
  603.          .
  604.          push   ds
  605.          pop    es
  606.          assume es:@data
  607.          lea    si,value0
  608.          lea    di,value1
  609.          call   mulf8
  610.  
  611.  
  612. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  613.  
  614. MULF8TEN:   multiply a float8 value by 10
  615. Source:     mulf8ten.asm (mulf8.asm, mpmul.asm)
  616.  
  617. 80x87 not required
  618.  
  619. Call with:  DS:[SI] pointing to float8 value
  620.             MulF8Ten is front-end code for MulF8, which saves ES and DI,
  621.             points ES:[DI] to f8 data equalling 10.0, calls MulF8, then
  622.             restores ES and DI.
  623. Returns:    if CF = 0, float8 value at DS:[SI] multiplied by 10.0
  624.             if CF = 1, the product is either 0 or infinity
  625. Uses:       CF; all other flags and registers are saved
  626. Example:
  627.  
  628. include asm.inc
  629.  
  630. extrn  mulf8ten:proc
  631.  
  632. .data
  633. value0   dq 1.234
  634.  
  635. .code
  636. ; program fragment assumes DS:@data
  637.          .
  638.          .
  639.          .
  640.          lea    si,value0
  641.          call   mulf8ten
  642.  
  643.  
  644. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  645.  
  646. SCALEF4:    scale a float4 value by an integer power of 2
  647. Source:     scalef4.asm
  648.  
  649. 80x87 not required
  650.  
  651. Call with:  DS:[SI] pointing to the float4 data
  652.             AL = scale factor (may be positive or negative)
  653. Returns:    CF = 0 if success: float4 value was properly scaled
  654.             CF = 1 if error: resulting float4 value would have overflowed
  655.                    float4 value unchanged in this case
  656. Uses:       CF; all other flags and all registers saved
  657. Example:
  658.  
  659. include asm.inc
  660.  
  661. .code
  662. ; program fragment assumes DS:@data
  663.         .
  664.         .
  665.         .
  666.         lea   si,float4data
  667.         mov   al,3             ; scale by (2^3) effectively multiplies by 8
  668.         call  scalef4
  669.         jc    oops             ; take remedial action if error
  670.  
  671.  
  672. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  673.  
  674. SCALEF8:    scale a float8 value by an integer power of 2
  675. Source:     scalef8.asm
  676.  
  677. 80x87 not required
  678.  
  679. Call with:  DS:[SI] pointing to the float8 data
  680.             AL = scale factor (may be positive or negative)
  681. Returns:    CF = 0 if success: float8 value was properly scaled
  682.             CF = 1 if error: resulting float8 value would have overflowed
  683.                    float8 value unchanged in this case
  684. Uses:       CF; all other flags and all registers saved
  685. Example:
  686.  
  687. include asm.inc
  688.  
  689. .code
  690. ; program fragment assumes DS:@data
  691.         .
  692.         .
  693.         .
  694.         lea   si,float8data
  695.         mov   al,3             ; scale by (2^3) effectively multiplies by 8
  696.         call  scalef8
  697.         jc    oops             ; take remedial action if error
  698.  
  699.  
  700.  
  701. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  702.  
  703. SORTF4HI:    sort an array of single-precision real numbers, highest first
  704. Source:      sortf4hi.asm
  705.  
  706. SORTF4LO:    sort an array of single-precision real numbers, lowest first
  707. Source:      sortf4lo.asm
  708.  
  709. 80x87 not required
  710.  
  711. Call with:  ES:[DI] pointing to the first of the array elements to be
  712.             sorted, CX = number of array elements
  713. Returns:    nothing
  714. Uses:       nothing; all registers and flags are saved
  715. Example:
  716.  
  717. include asm.inc
  718.  
  719. extrn  sortf4hi:proc
  720.  
  721. .data
  722. floatdata   dd 1500 dup(0)
  723.  
  724. .code
  725. ; program fragment assumes DS:@data
  726. ; program provides values for the array
  727.         .
  728.         .
  729.         push    ds
  730.         pop     es
  731.         assume  es:@data
  732.         lea     di,floatdata
  733.         mov     cx,1500           ; sort entire array
  734.         call    sortf4hi          ; highest value first
  735.  
  736.  
  737.  
  738. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  739.  
  740. SUBF4:       subtract one float4 value from another
  741. Source:      subf4.asm (addf4.asm)
  742.  
  743. SUBF8:       subtract one float8 value from another
  744. Source:      subf8.asm (addf8.asm)
  745.  
  746. 80x87 not required
  747.  
  748. Call with:   DS:[SI] pointing to value0
  749.              ES:[DI] pointing to value1
  750.              the number at ES:[DI] is subtracted from the number at DS:[SI]
  751.              with the result replacing the number at DS:[SI]
  752. Returns:     if CF = 0, DS:[SI] points to value0 - value1
  753.              if CF = 1, the operation would result in an overflow;
  754.                 neither value is changed
  755. Uses:        nothing; all registers and flags are saved
  756. Example:
  757.  
  758. include asm.inc
  759.  
  760. extrn subf4:proc
  761.  
  762. .data
  763. value0  dd 123.456
  764. value1  dd -67.4
  765.  
  766. .code
  767. ; program fragment assumes DS:@data
  768.          .
  769.          .
  770.          .
  771.         push    ds
  772.         pop     es           ; ES = DS
  773.         assume  es:@data
  774.         lea     si,value0
  775.         lea     di,value1
  776.         call    subf4
  777.